package classes.graphicalEngine
{
	import flash.events.*;
	import flash.geom.*;
	
	import mx.core.*;
	import mx.managers.PopUpManager;
	import components.GraphicalEngineComp;
	import mx.controls.Alert;

	public class Player extends GameObject
	{
		// direction that the player object should move to (1 for right/down, -1 for left/up)
		protected var direction:Point = new Point(0, 0);
		// destination that the player object should move to (1 for right/down, -1 for left/up)
		public var destination:Point;
		// movement speed of the moving player
		protected static const speed:Number = 100;
		
		protected var positionGPS:Point = new Point(0,0);
		protected var destinationGPS:Point = new Point(0,0);
		protected var cheminGPS:Array = new Array();
				
		// default map dimensions
		protected var defaultMapWidth:Number = GameObjectManager.defaultMapWidth;
		protected var defaultMapHeight:Number = GameObjectManager.defaultMapHeight;
		protected var fullSizeMapWidth:Number = GameObjectManager.fullSizeMapWidth;
		protected var fullSizeMapHeight:Number = GameObjectManager.fullSizeMapHeight;
		
		public function Player()
		{			
			
		}
		
		public function startupPlayer(defaultXPosition:Number = -1, defaultYPosition:Number = -1):void
		{
			if (defaultXPosition < 0) defaultXPosition = defaultMapWidth / 2;
			if (defaultYPosition < 0) defaultYPosition = defaultMapHeight / 2;
			startupGameObject(ResourceManager.ExtractorGraphics, new Point(defaultXPosition, defaultYPosition), ZOrders.PlayerZOrder);
			destination = position.clone();
			updatePositionGPS();
			destinationGPS = positionGPS.clone();
		}
		
		override public function shutdown():void
		{
			super.shutdown();
		}
		
		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);

			if (!GameCamera.position.equals(GameCamera.destination))
			{
				position.x -= GameCamera.xShifting;
				position.y -= GameCamera.yShifting;
				destination.x -= GameCamera.xShifting;
				destination.y -= GameCamera.yShifting;
				// updatePositionGPS();
				// updateDestinationGPS(); <-- a priori FAUX -- la destinationGPS ne change pas lors du deplacement de la cam
				// contrairement à la destination locale...
			}

			if (position.x != destination.x || position.y != destination.y)
			{
				GameObjectManager.needToBeRefreshed = true;
				var xShifting:Number = direction.x * speed * dt;
				var yShifting:Number = direction.y * speed * dt;
				
				if (Math.abs(xShifting) < Math.abs(destination.x - position.x))
				position.x += xShifting;
				else
				position.x = destination.x;
				
				if (Math.abs(yShifting) < Math.abs(destination.y - position.y))
				position.y += yShifting;
				else
				position.y = destination.y;
				
				updatePositionGPS();
				if (positionGPS.x == destinationGPS.x && positionGPS.y == destinationGPS.y)
				{
					// Alert.show("positionGPS == destinationGPS");
					if (cheminGPS.length > 0)
					{
						destinationGPS = cheminGPS.pop();
						updateLocalDestinationFromGPSAddress(destinationGPS);
					}
				}
				setGoodDirection();
			}
		}
		
		override public function click(event:MouseEvent):void
		{
			// setting player new destination
			destination.x = (int((event.localX) / GameObjectManager.defaultGrapicsSizeMultiple) * GameObjectManager.defaultGrapicsSizeMultiple) - int((graphics.bitmap.width-GameObjectManager.defaultGrapicsSizeMultiple)/2);
			destination.y = (int((event.localY) / GameObjectManager.defaultGrapicsSizeMultiple) * GameObjectManager.defaultGrapicsSizeMultiple) - (graphics.bitmap.height-GameObjectManager.defaultGrapicsSizeMultiple);
			
			// keeping player on the screen
			if (destination.x < 0)
				destination.x = 0;
			if (destination.x > defaultMapWidth - graphics.bitmap.width)
				destination.x = defaultMapWidth - graphics.bitmap.width;// deplacer la GameObjectManager.maCamera ?
			if (destination.y < 0)
				destination.y = 0;
			if (destination.y > defaultMapHeight - graphics.bitmap.height )
				destination.y = defaultMapHeight - graphics.bitmap.height ;// deplacer la GameObjectManager.maCamera ?

			// checking if the destination is a navigable cell
			var newGPSDestination:Point = updateDestinationGPS();
			// Alert("" + newGPSDestination.toString() + " = " + GameObjectManager.carteGPS[newGPSDestination.y][newGPSDestination.x].toString());
				
			var navigable:Boolean = false;
			if (newGPSDestination.y >= GameObjectManager.carteGPS.length ||
				newGPSDestination.x >= GameObjectManager.carteGPS[newGPSDestination.y].length)
				Alert.show("newGPSDestination hors carteGPS !\ny = "+newGPSDestination.y+" x = "+newGPSDestination.x+
					"\ncarte.Y = " + GameObjectManager.carteGPS.length +
					" carte.X = " + GameObjectManager.carteGPS.carteGPS[newGPSDestination.y].length);
			if (GameObjectManager.carteGPS[newGPSDestination.y][newGPSDestination.x] == 0) navigable = true;

			if (! navigable)
			{
				destination = position.clone();
				updateDestinationGPS();
			}
			else
			{
				if (GraphicalEngineComp.menuContextuel && GraphicalEngineComp.menuContextuel.isPopUp) 	
					PopUpManager.removePopUp(GraphicalEngineComp.menuContextuel);
				cheminGPS = GameObjectManager.GPS.Astare(positionGPS,newGPSDestination,GameObjectManager.carteGPS,true);
				// Alert.show(position.toString() + " " + positionGPS.toString() + "\n\n" + destination.toString() + " " + newGPSDestination.toString() + " " + destinationGPS.toString() + "\n\n" + cheminGPS.toString());
				destinationGPS = cheminGPS.pop();
				updateLocalDestinationFromGPSAddress(destinationGPS);
				// Alert.show(cheminGPS.toString());
				/*
				var carte:String = "";
				for (var y:int = 0; y<GameObjectManager.carteGPS.length; y++)
				{
					carte += GameObjectManager.carteGPS[y].toString().substr(0,40);
					carte += "\n";
				}
				Alert.show(carte);
				*/
				setGoodDirection();
			}
		}
		
		protected function setGoodDirection():void
		{
			if (destination.x < position.x)
			{
				direction.x = -1;
			}
			else if (destination.x > position.x)
			{
				direction.x = 1;
			}
			else direction.x = 0;
			
			if (destination.y < position.y)
			{
				direction.y = -1;
			}
			else if (destination.y > position.y)
			{
				direction.y = 1;
			}
			else direction.y = 0;
		}
		
		// udate la position GPS par rapport à la position locale
		protected function updatePositionGPS():Point
		{
			positionGPS.x = int((GameCamera.position.x + position.x + (graphics.bitmap.width-GameObjectManager.defaultGrapicsSizeMultiple)/2) / GameObjectManager.defaultGrapicsSizeMultiple);
			positionGPS.y = int((GameCamera.position.y + position.y + graphics.bitmap.height - GameObjectManager.defaultGrapicsSizeMultiple)/ GameObjectManager.defaultGrapicsSizeMultiple);
			return positionGPS;
		}

		// udate la destination GPS par rapport à la destination locale
		protected function updateDestinationGPS():Point
		{
			destinationGPS.x = int((GameCamera.position.x + destination.x + (graphics.bitmap.width-GameObjectManager.defaultGrapicsSizeMultiple)/2)/GameObjectManager.defaultGrapicsSizeMultiple);
			destinationGPS.y = int((GameCamera.position.y + destination.y + graphics.bitmap.height - GameObjectManager.defaultGrapicsSizeMultiple)/GameObjectManager.defaultGrapicsSizeMultiple);
			return destinationGPS;
		}
		
		// update la destination locale par rapport à la destination GPS
		protected function updateLocalDestinationFromGPSAddress(GPSAddress:Point):Point
		{
			var localAddress:Point = new Point();
			localAddress.x = GPSAddress.x * GameObjectManager.defaultGrapicsSizeMultiple - GameCamera.position.x;
			localAddress.y = GPSAddress.y * GameObjectManager.defaultGrapicsSizeMultiple - GameCamera.position.y;
			destination.x = localAddress.x - int((graphics.bitmap.width-GameObjectManager.defaultGrapicsSizeMultiple)/2);
			destination.y = localAddress.y - (graphics.bitmap.height-GameObjectManager.defaultGrapicsSizeMultiple);
			return destination;
		}

	}
}